﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Xna.Framework;
using TinyEngine.Core;
using TinyEngine.Core.Asset;
using TinyEngine.Core.Entities;
using TinyEngine.Editor.Extensibility;
using TinyEngine.Editor.Extensibility.Controls;
using TinyEngineEditor.SceneViewer;


namespace TinyEngine.Editor.DefaultPlugins.EntityInspector
{
    public partial class EntityInspector : UserControl
    {
        EntityItem item = new EntityItem();
        public EntityInspector()
        {
            InitializeComponent();
            this.DataContext = item;

            EditorSession.Instance.ItemSelected += new Action<IEntity>(Instance_ItemSelected);
            this.Loaded += new RoutedEventHandler(EntityInspector_Loaded);
        }

        void EntityInspector_Loaded(object sender, RoutedEventArgs e)
        {
            gfxControl = new SceneItemsGraphicsDeviceControl();
            basicGameRenderer1.Load(gfxControl);
        }

        void Instance_ItemSelected(IEntity obj)
        {
            this.item.Entity = obj;

            CheckAssetHolder();

            ConstructControl();

            gfxControl.SetItem(obj);
        }
        SceneItemsGraphicsDeviceControl gfxControl;
        private void ConstructControl()
        {
            panelControls.Children.Clear();

            //hard coding a few types to test

            CreateControlForProperty("Position", this.item.Entity);
            CreateControlForProperty("Origin", this.item.Entity);
            CreateControlForProperty("SourceRectangle", this.item.Entity);
            CreateControlForProperty("Tint", this.item.Entity);
            CreateControlForProperty("Visible", this.item.Entity);
            CreateControlForProperty("Layer", this.item.Entity);
            
        }

        private void CreateControlForProperty(string propName, IEntity iEntity)
        {
            var property = iEntity.GetType().GetProperty(propName);
            if (property == null) return;

            if (property.PropertyType == typeof(Microsoft.Xna.Framework.Color))
            {
                var btn = new System.Windows.Controls.Button();
                btn.Content = "Choose color";
                btn.Margin = new Thickness(12, 12, 12, 0);
                btn.Click += new RoutedEventHandler(delegate
                    {
                        var col = new System.Windows.Forms.ColorDialog();
                        var res = col.ShowDialog();
                        if(res == System.Windows.Forms.DialogResult.OK)
                        {
                            property.SetValue(iEntity, new Microsoft.Xna.Framework.Color(
                                ((System.Drawing.Color)col.Color).R * 255,
                                ((System.Drawing.Color)col.Color).G * 255,
                                ((System.Drawing.Color)col.Color).B * 255), null);
                            
                            RefreshUI();
                        }

                    });

                panelControls.Children.Add(btn);
            }
            if (property.PropertyType == typeof(bool))
            {
                var btn = new System.Windows.Controls.CheckBox();
                btn.Content = property.Name;
                btn.Margin = new Thickness(12, 12, 12, 0);
                btn.IsChecked = (bool)property.GetValue(iEntity, null);
                btn.Checked += new RoutedEventHandler(delegate
                {
                    var b = false;
                    if (btn.IsChecked.HasValue && btn.IsChecked.Value)
                    {
                        b = true;
                    }
                    property.SetValue(iEntity, b, null);

                    RefreshUI();
                });

                btn.Unchecked += new RoutedEventHandler(delegate
                {
                    var b = false;
                    if (btn.IsChecked.HasValue && btn.IsChecked.Value)
                    {
                        b = true;
                    }
                    property.SetValue(iEntity, b, null);

                    RefreshUI();
                });

                panelControls.Children.Add(btn);
            }

            if (property.PropertyType == typeof(Microsoft.Xna.Framework.Rectangle?))
            {
                var itemCtrl = new RectangleControl(property.Name);
                itemCtrl.Rectangle = (Microsoft.Xna.Framework.Rectangle?)property.GetValue(iEntity, null);
                itemCtrl.ValueChanged += new Action(delegate
                {
                    property.SetValue(iEntity, itemCtrl.Rectangle, null);
                    RefreshUI();
                });

                panelControls.Children.Add(itemCtrl);
            }
            if (property.PropertyType == typeof(Vector2))
            {
                var itemCtrl = new VectorControl(property.Name);
                itemCtrl.Vector2 = (Vector2)property.GetValue(iEntity, null);
                itemCtrl.VectorChanged+=new Action(delegate
                {
                    property.SetValue(iEntity, itemCtrl.Vector2, null);
                    RefreshUI();
                });

                panelControls.Children.Add(itemCtrl);
            }
            if (property.PropertyType == typeof(Single))
            {
                var itemCtrl = new NumberControl(property.Name);
                itemCtrl.Number = (Single)property.GetValue(iEntity, null);
                itemCtrl.NumberChanged += new Action(delegate
                {
                    property.SetValue(iEntity, itemCtrl.Number, null);
                    RefreshUI();
                });

                panelControls.Children.Add(itemCtrl);
            }
            if (property.PropertyType == typeof(Vector3))
            {
                var itemCtrl = new VectorControl(property.Name);
                itemCtrl.Vector = (Vector3)property.GetValue(iEntity, null);
                itemCtrl.VectorChanged += new Action(delegate
                {
                    property.SetValue(iEntity, itemCtrl.Vector, null);
                    RefreshUI();
                });

                panelControls.Children.Add(itemCtrl);
            }
        }

        private void RefreshUI()
        {
            EditorSession.RequestSceneRefresh();
        }

        private void CheckAssetHolder()
        {
            IAssetHolder<SpriteAsset> spriteHolder = this.item.Entity as IAssetHolder<SpriteAsset>;
            if (spriteHolder == null)
            {
                btnChooseSprite.Visibility = System.Windows.Visibility.Collapsed;
                return;
            }

            btnChooseSprite.Visibility = System.Windows.Visibility.Visible;
        }

        private void btnChooseSprite_Click(object sender, RoutedEventArgs e)
        {
            var chooser = new AssetExplorer.AssetChooser();
            chooser.SpriteChosen += new Action<SpriteAsset>(chooser_SpriteChosen);
            EditorSession.LaunchDialogWindow(chooser);
        }

        void chooser_SpriteChosen(SpriteAsset obj)
        {
            IAssetHolder<SpriteAsset> entity = item.Entity as IAssetHolder<SpriteAsset>;
            entity.AssetName = obj.Name;
        }

    }

    public class EntityItem : INotifyPropertyChanged
    {
        private IEntity entity;
        public IEntity Entity 
        {
            get { return entity; }
            set
            {
                entity = value;
                NotifyPropertyChanged("Name");
            }

        }
        public void NotifyPropertyChanged(string name)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
        public EntityItem()
        {
            Entity = new NullEntity();
            Entity.Name = "Entity 1";
        }
        public string Name
        {
            get
            {
                
                return Entity.Name;
            }
            set
            {
                Entity.Name = value;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}
